﻿using AutoMapper;
using MediatR;
using Medical.Api.Write.Application.Command.Wms.WmsStorageCommand;
using Medical.Domain.Wms;
using Medical.ErrorCode;
using Medical.Interstructrue.Base;
using Medical.Interstructrue;

namespace Medical.Api.Write.Application.Handler.Wms.WmsStorageHandler
{

    /// <summary>
    /// 入库批量逻辑删除处理器，实现主表单条、明细多条的逻辑删除
    /// </summary>
    public class DelBatchStorageHandlter : IRequestHandler<DelBatchStorageCommand, ApiResult<int>>
    {
        /// <summary>
        /// 日志记录器
        /// </summary>
        private readonly ILogger<DelBatchStorageHandlter> logger;
        /// <summary>
        /// AutoMapper实例
        /// </summary>
        private readonly IMapper mapper;
        /// <summary>
        /// 入库主表仓储
        /// </summary>
        private readonly IBaseRepository<WmsStorage> wmsStorageRep;
        /// <summary>
        /// 入库明细仓储
        /// </summary>
        private readonly IBaseRepository<WmsStorageDetail> wmsStorageDetailRep;
        /// <summary>
        /// 数据库上下文
        /// </summary>
        private readonly MedicalDbContext dbContext;

        /// <summary>
        /// 构造方法，注入日志、映射、仓储和DbContext依赖
        /// </summary>
        /// <param name="logger">日志</param>
        /// <param name="mapper">automapper</param>
        /// <param name="wmsStorageRep">入库主表仓储</param>
        /// <param name="wmsStorageDetailRep">入库明细仓储</param>
        /// <param name="dbContext">数据库上下文</param>
        public DelBatchStorageHandlter(ILogger<DelBatchStorageHandlter> logger, IMapper mapper, IBaseRepository<WmsStorage> wmsStorageRep, IBaseRepository<WmsStorageDetail> wmsStorageDetailRep, MedicalDbContext dbContext)
        {
            this.logger = logger;
            this.mapper = mapper;
            this.wmsStorageRep = wmsStorageRep;
            this.wmsStorageDetailRep = wmsStorageDetailRep;
            this.dbContext = dbContext;
        }

        /// <summary>
        /// 逻辑删除入库（主表单条，字表多条），带事务和异常处理
        /// </summary>
        /// <param name="request">删除命令，包含主表Id</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>删除结果，主表和明细影响行数</returns>
        public Task<ApiResult<int>> Handle(DelBatchStorageCommand request, CancellationToken cancellationToken)
        {
            var result = new ApiResult<int>();
            // 启动数据库事务，保证主表和明细同时逻辑删除
            using var transaction = dbContext.Database.BeginTransaction();
            try
            {
                // 1. 获取主表
                var storage = wmsStorageRep.GetModel(request.Id);
                if (storage == null)
                {
                    // 未找到主表，返回NotFound
                    result.Code = ApiEnums.NotFound;
                    result.Msg = $"未找到Id为{request.Id}的入库记录";
                    result.Data = 0;
                    logger.LogWarning($"逻辑删除失败：未找到Id为{request.Id}的入库记录");
                    return Task.FromResult(result);
                }
                // 2. 仅未审批（AuditState=false）状态可删除
                if (storage.AuditState)
                {
                    result.Code = ApiEnums.Fail;
                    result.Msg = "仅未审批状态可删除";
                    result.Data = 0;
                    logger.LogWarning($"逻辑删除失败：Id为{request.Id}的入库记录已审批");
                    return Task.FromResult(result);
                }
                // 3. 逻辑删除主表
                storage.IsDeleted = true;
                var updateMain = wmsStorageRep.Update(storage);

                // 4. 获取所有明细
                var details = wmsStorageDetailRep.GetAll().Where(d => d.StorageId == request.Id && !d.IsDeleted).ToList();
                foreach (var detail in details)
                {
                    detail.IsDeleted = true;
                }
                int updateDetailCount = 0;
                if (details.Count > 0)
                {
                    // 批量更新明细表
                    updateDetailCount = wmsStorageDetailRep.UpdateRange(details);
                }

                // 提交事务
                transaction.Commit();
                result.Code = ApiEnums.Success;
                result.Msg = $"逻辑删除成功，主表1条，明细{details.Count}条";
                result.Data = updateMain + updateDetailCount;
                logger.LogInformation($"逻辑删除成功，主表Id: {request.Id}，明细数: {details.Count}");
            }
            catch (Exception ex)
            {
                // 发生异常时回滚事务，保证数据一致性
                transaction.Rollback();
                result.Code = ApiEnums.Error;
                result.Msg = $"逻辑删除异常: {ex.Message}";
                result.Data = 0;
                logger.LogError(ex, $"逻辑删除异常，Id: {request.Id}");
            }
            return Task.FromResult(result);
        }
    }
}
